/**
 * \file feld.h
 *
 * \brief Beinhaltet die Klasse Feld.
 */

#ifndef _FELD_H_
#define _FELD_H_

#include <vector>

#include "state.h"
#include "zustand.h"
#include "viewer.h"
#include "regelwerk.h"
#include "HeightWidth.h"

class Viewer;

/**
 * \brief Stellt das Spielfeld eines Game-Of-Life-Spiels dar.
 */
class Feld {
 private:
        HeightWidth hw;
        int gen;
				/**
				 * \brief Die aktuelle Belegung des Feldes.
				 */
        std::vector<bool> array; // Speichert die Werte genau so platzsparend wie bitset, hat aber eine dynamische Größe.
				
				/**
				 * \brief Ein Zwischenspeicher, der von nextGen() benutzt wird. Der Speicherplatz wird aus Performancegründen nur einmal angefordert.
				 */
        std::vector<bool> buffer;// = array;
				
				/**
				 * \brief Ein Zwischenspeicher für den Viewer.
				 */
        std::vector<bool> drawarray;
        Regelwerk *r;
        Viewer *v;
        Zustand *z;// wird benötigt, um während der Berechnung die Berechnung stoppen zu können
				/**
				 * \brief Gibt den Index desjenigen Vectorelements zurück, dessen zweidimensionale Koordinaten im Feld übergeben werden.
				 *
				 * \param pos Die (x,y)-Koordinaten desjenigen Feldes, deren Vectorindex bestimmt werden soll.
				 */
        inline int posToInd(HeightWidth pos) const;
 public:
        /**
				 * \brief Berechnet die nächste Generation des Feldes. Die alte Belegung wird dabei unwiderruflich überschrieben.
				 */
        void nextGen();
				
				/**
				 * \brief Weist dem Feld ein Regelwerk zu.
				 *
				 * \param _r Zeiger auf ein Regelwerk-Objekt, das dem Feld zugrundeliegen soll.
				 */
        void setRegelwerk (Regelwerk *_r);
				
				/**
				 * \brief Weist dem Feld einen Viewer zu.
				 *
				 * \param _v Zeiger auf ein Viewer-Objekt, welches das Feld anzeigen wird.
				 */
        void setViewer (Viewer *_v);
				
				/**
				 * \brief Weist dem Feld ein Zustandsobjekt zu.
				 *
				 * \param _z Zeiger auf das Zustandsobjekt, welches den Zustand des Feldes beschreiben wird.
				 */
        void setZustand (Zustand *_z);
				
				/**
				 * \brief Gibt einen Zeiger auf das dem Feld zugrundeliegende Regelwerk zurück.
				 */
        Regelwerk * getRegelwerk () const;
				
				/**
				 * \brief Gibt einen Zeiger auf den das Feld anzeigenden Viewer zurück.
				 */
        Viewer *  getViewer ();
				
				/**
				 * \brief Setzt die Höhe und Breite des Feldes.
				 *
				 * \param _hw HeightWidth-Objekt, das die gewünschte Höhe und Breite des Feldes enthält.
				 */
        void setHeightWidth(HeightWidth _hw);
				
				/**
				 * \brief Gibt die Höhe des Spielfelds zurück.
				 */
        int getHeight() const;
				
				/**
				 * \brief Gibt die Breite des Spielfelds zurück.
				 */
        int getWidth() const;
				
				/**
				 * \brief Weist einer Zelle im Feld einen bestimmten Lebendigkeitswert zu.
				 *
				 * \param pos Die (x, y)-Position der Zelle im Feld.
				 * \param value Der zugewiesene Lebendigkeitswert. Falsch bedeutet tot, und wahr bedeutet lebendig.
				 */
        void setCell(HeightWidth pos, bool value);
				
				
				/**
				 * \brief Gibt den Lebendigkeitswert einer Zelle im Feld zurück. Falsch bedeutet tot, und wahr bedeutet lebendig.
				 *
				 * \param pos Die (x, y)-Position der Zelle im Feld.
				 */
        bool getCell(HeightWidth pos) const;

				/**
				 * \brief Gibt den Lebendigkeitswert einer Zelle im Viewer-Zwischenspeicher zurück. Falsch bedeutet tot, und wahr bedeutet lebendig.
				 *
				 * \param pos Die (x, y)-Position der Zelle im Viewer-Zwischenspeicher.
				 */
				bool getCellV(HeightWidth pos) const;
				
				/**
				 * \brief Invertiert den Lebendigkeitswert einer Zelle im Feld. Aus tot wird lebendig und umgekehrt.
				 *
				 * \param pos Die (x, y)-Position der Zelle im Feld.
				 */
        void invertCell(HeightWidth pos);
				
				/**
				 * \brief Gibt die Anzahl der Generationen seit dem Start der Simulation zurück.
				 */
        int getGen() const;
				
				/**
				 * \brief Setzt die Anzahl der Generationen seit dem Start neu.
				 *
				 * \param _gen Die neue Anzahl der Generationen.
				 */
        void setGen(int _gen);
				
				/**
				 * \brief Kopiert den Feldinhalt in den Viewer-Zwischenspeicher.
				 */
        void copyFieldToViewer();
				
				
				/**
				 * \brief Ein normaler Copy-Konstruktor.
				 *
				 * \param Feld Dasjenige Feld, dessen Inhalt kopiert wird.
				 */
        Feld( const Feld&);
				
				/**
				 * \brief Der Standardkonstruktor des Feldes.
				 */
        Feld();
				
				/**
				 * \brief Der Standarddestruktor des Feldes.
				 */
        ~Feld(); 
};

#endif

